using UnityEngine;
using System.Collections;
using DG.Tweening;
using UnityEngine.UI;  // 引用 UI 组件

public class ColorFlowToRawimage : MonoBehaviour
{
    public int width = 256;
    public int height = 256;
    public float scalespeed = 1f;

    [SerializeField, Range(1, 10)]
    int _fractalLevel = 1;

    public Gradient[] _colorGradient;
    private Texture2D texture;

    private int curGradientIndex = 0;
    private Gradient curGradient;

    private bool isAuto = true;

    private float alphaTime = 0.25f;

    private RawImage rawImage;  // 用来显示纹理的 RawImage 组件

    void Start()
    {
        // 获取 RawImage 组件
        rawImage = GetComponent<RawImage>();
        
        if (rawImage == null)
        {
            Debug.LogError("RawImage 组件未找到！");
            return;
        }

        // Initialize texture
        texture = new Texture2D(width, height);
        texture.wrapMode = TextureWrapMode.Clamp;

        // 将纹理设置为 RawImage 的纹理
        rawImage.texture = texture;

        // Set initial gradient
        curGradient = _colorGradient[curGradientIndex];
    }

    // Coroutine to play the effect transition between gradients
    private IEnumerator PlayEffect(int index)
    {
        if (curGradientIndex != index)
        {
            Debug.Log("播放效果 : " + index);

            // 使用 UI 组件的透明度变化
            DOTween.To(() => rawImage.color.a, x => rawImage.color = new Color(rawImage.color.r, rawImage.color.g, rawImage.color.b, x), 0f, alphaTime)
                .OnComplete(() => { });

            yield return new WaitForSeconds(alphaTime);

            curGradientIndex = index;
            Debug.Log("curGradientIndex : " + curGradientIndex);
            curGradient = _colorGradient[curGradientIndex];

            DOTween.To(() => rawImage.color.a, x => rawImage.color = new Color(rawImage.color.r, rawImage.color.g, rawImage.color.b, x), 1f, 0.25f)
                .OnComplete(() => {
                    Debug.Log("材质透明度渐变完成");
                });
        }
    }

    void Update()
    {
        // Switch effects using space key
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Cycle through the gradient effects
            curGradientIndex = (curGradientIndex + 1) % _colorGradient.Length;
            Debug.Log("curGradientIndex : " + curGradientIndex);
            curGradient = _colorGradient[curGradientIndex];
            StartCoroutine(PlayEffect(curGradientIndex));
        }

        // Update texture based on Perlin noise and fractal level
        UpdateTexture((x, y, t) => Perlin.Fbm(x, y, t, _fractalLevel));
    }

    // Update texture with Perlin noise values
    private void UpdateTexture(System.Func<float, float, float, float> generator)
    {
        var scale_x = 1.0f / width;
        var scale_y = 1.0f / height;
        var time = Time.time * scalespeed;

        // Fill texture with colors based on fractal noise and gradients
        for (var y = 0; y < height; y++)
        {
            for (var x = 0; x < width; x++)
            {
                var n = generator.Invoke(x * scale_x, y * scale_y, time);
                texture.SetPixel(x, y, curGradient.Evaluate(n / 1.4f + 0.5f));
            }
        }
        texture.Apply();
    }
}
